import { message, notification } from "antd";
import { useCallback } from "react";
import { useRecoilState } from "recoil";

import { userState } from "./../stores/user";

/**公共的 HTTP 请求封装 */

type UploadFileType = {
  endpoint?: string;
  data: {
    [key in string]: Blob | Blob[] | string | string[] | File | File[] | number;
  };
  token?: string;
};

const uploadFormData = (endpoint: string, { data, token }: UploadFileType) => {
  return window
    .fetch(`${endpoint}`, {
      method: "POST",
      headers: {
        token: token || "",
      },
      body: dataToFormData(data),
    })
    .then(async (response) => {
      if (response.status === 401) {
        // await auth.logout();
        return Promise.reject({ message: "请重新登录" });
      }
      const data = await response.json();
      if (data.code === 100) {
        // await auth.logout();
        // window.location.href = '/login';

        return Promise.reject({ message: "请重新登录" });
      }
      if (data.code === 200) {
        if (data.message && data.message.length > 0) {
          notification.success({
            message: data.message,
          });
        }
        return Promise.resolve(data.data as any);
      }
      message.error(data.message);
      return Promise.reject({ ...data, msg: data.data });
    })
    .catch((e) => {
      return Promise.reject(e);
    });
};

/**
 * 将对象类型转换为 formData 类型
 * @param data
 */
const dataToFormData = (data: UploadFileType["data"]): FormData => {
  const formData = new FormData();
  Object.keys(data).forEach((key) => {
    const value = data[key];
    if (Array.isArray(value)) {
      value.forEach((v) => {
        formData.append(key, v);
      });
    } else {
      if (typeof value === "number") {
        formData.append(key, value + "");
      } else {
        formData.append(key, value);
      }
    }
  });
  return formData;
};

export const useUpload = () => {
  const [user] = useRecoilState(userState);
  return useCallback(
    (...[endpoint, config]: Parameters<typeof uploadFormData>) =>
      uploadFormData(endpoint, { ...config, token: user?.token || "" }),
    [user?.token]
  );
};
